#服务端
import socket
import traceback
import threading
'''
群聊
--join:加入，必须填用户名，格式： --join:你的名字
--group:群发  格式：--group:消息
--chat:格式：--chat:好友名:消息
--list:列出所有的在线好友
--exit:退出
'''
#放了用户的连接sockt
onlineusers=[]
#放了用户名
usernames=[]
def exit(s):
    try:
        pos=onlineusers.index(s)
        usernames.pop(pos)
        onlineusers.pop(pos)
        s.close()
    except:
        pass
def list(s):
    s.sendall(str(usernames).encode("utf-8"))

def join(s,name):#防止重名
    onlineusers.append(s)
    usernames.append(name)
    s.sendall("欢迎加入聊天室".encode("utf-8"))
    sendgroup(s,name+"加入了群")
def sendgroup(s,msg):
    for x in onlineusers:
        if not x:
            continue
        if x!=s:
            x.sendall(msg.encode("utf-8"))
def send(s,to,xiaoxi):
    try:
        pos =usernames.index(to)
        onlineusers[pos].sendall(xiaoxi.encode("utf-8"))
        s.sendall("消息发送成功")
    except Exception as e:
        traceback.print_exc()
        s.sendall(("消息出现错误："+str(e)).encode("utf-8"))
def talk(s,addr):
    print("本次连接的地址信息：", addr)
    try:
        while True:
            msg = str(s.recv(2048).decode("utf-8").strip())
            print("消息是：",msg)
            if not msg or not msg.startswith("--"):
                s.sendall("消息格式非法".encode("utf-8"))
                continue
            if msg=="--exit":
                exit(s)
                break
            elif msg=="--list":
                list(s)
            elif msg.startswith("--join:"):
                name=msg[7:]
                join(s,name)
            elif msg.startswith("--group:"):
                msg = msg.split("--group:")[1]
                sendgroup(s,msg)
            elif msg.startswith("--chat:"):
                msg=msg[7:]#name:msg
                to,xiaoxi=msg.split(":")
                send(s,to,xiaoxi)
            else:
                s.sendall("未处理的消息格式1".encode("utf-8"))
    except Exception as e:
        traceback.print_exc()
        exit(s)
        print(addr,"断开了。异常信息如上！", sep="")

    finally:
        if s:
            s.close()
if __name__ == '__main__':
    st=socket.socket()
    st.bind(("192.168.100.85",9998))
    st.listen(10)
    print("聊天室启动")
    while True:
        s,addr=st.accept()
        #启动一个线程，为这次连接服务
        th=threading.Thread(target=talk,args=(s,addr))
        th.start()